package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.config.cache.TsCache;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Random;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Resource
    private AlbumInfoMapper albumInfoMapper;
    @Resource
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Resource
    private AlbumStatMapper albumStatMapper;
    @Resource
    private RabbitService rabbitService;

    @Resource
    private RedissonClient redissonClient;
    @Override
    //事务  出现异常就回滚
    @Transactional(rollbackFor = Exception.class)
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo, Long userId) {
        //表一  album_info
        AlbumInfo albumInfo = new AlbumInfo();
        // 属性赋值  工具类进行拷贝即可  不用一个一个的  get set
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        // 差三个数据   userId , tracks_for_free   status
        // userId
        albumInfo.setUserId(userId);
        // tracks_for_free 免费试听集数    看看前端传过来类型 如果是付费的 就有免费试听集数  自己定义
        if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())) {
            //说明是付费的  有免费试听集数  自定义即可
            albumInfo.setTracksForFree(8);
        }
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        albumInfoMapper.insert(albumInfo);
        //表二  album_attribute_value   数据都在albumInfoVo中 所以
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        // 判断 是否有数据
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
                // 新建对象
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                // 赋值  copy 拷贝即可
                BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
                //上面albumInfoMapper执行了insert方法 且type = IdType.AUTO 属性配置  所以返回了主键id
                albumAttributeValue.setAlbumId(albumInfo.getId());
                // 数据保存
                albumAttributeValueMapper.insert(albumAttributeValue);
            }
        }

        //表三  album_stat
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_PLAY);
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_SUBSCRIBE);
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_BROWSE);
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_COMMENT);

        if ("1".equals(albumInfoVo.getIsOpen())){
            // 上架
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumInfo.getId());
        }
    }

    public void saveAlbumStat(Long albumId, String statPlay) {
        //数据保存
        AlbumStat albumStart = new AlbumStat();
        albumStart.setAlbumId(albumId);
        albumStart.setStatType(statPlay);
        albumStart.setStatNum(new Random().nextInt(100000));
        albumStatMapper.insert(albumStart);
    }

    @Override
    public IPage<AlbumListVo> findUserAlbumPage(Page<AlbumListVo> albumListVoPage, AlbumInfoQuery albumInfoQuery) {
        //查询数据 专辑基本信息  +  专辑统计信息
        return albumInfoMapper.selectUserAlbumPage(albumListVoPage, albumInfoQuery);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAlbumInfo(Long albumId) {
        // album_attribute_value
        //album_info
        //album_stat
        albumInfoMapper.deleteById(albumId);
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));
        rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_LOWER,albumId);
    }

    @TsCache(prefix = RedisConstant.ALBUM_INFO_PREFIX + "AlbumInfoVo:")
    @Override
    public AlbumInfo getAlbumInfo(Long albumId) {
        AlbumInfo albumInfo = this.getById(albumId);
        if (albumInfo != null) {
            albumInfo.setAlbumAttributeValueVoList(albumAttributeValueMapper.selectList(
                    new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId)
            ));
        }
        return albumInfo;
    }

    @Override
    public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
        // 1.更新album_info表
        AlbumInfo albumInfo = new AlbumInfo();
        // 属性赋值
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setId(albumId);
        // 更新数据
        albumInfoMapper.updateById(albumInfo);
        // 2.更新album_attribute_value表 先删除再 新增
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        //album_attribute_value 添加数据
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        //判断
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
                // 新建对象
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                // 赋值  copy 拷贝即可
                BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
                //上面albumInfoMapper执行了insert方法 且type = IdType.AUTO 属性配置  所以返回了主键id
                albumAttributeValue.setAlbumId(albumInfo.getId());
                // 数据保存
                albumAttributeValueMapper.insert(albumAttributeValue);
            }
        }
        if ("1".equals(albumInfoVo.getIsOpen())){
            // 上架
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumId);

        } else {
            // 下架
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_LOWER,albumId);
        }
    }

    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        Page<AlbumInfo> albumInfoPage = new Page<>(1, 10);
        IPage<AlbumInfo> albumInfoIPage = albumInfoMapper.selectPage(albumInfoPage,
                new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId)
                        .select(AlbumInfo::getId,AlbumInfo::getAlbumTitle).orderByDesc(AlbumInfo::getId));
        return albumInfoIPage.getRecords();
    }

    @TsCache(prefix = RedisConstant.ALBUM_INFO_PREFIX + "AlbumStats:")
    @Override
    public AlbumListVo getAlbumStatistics(Long albumId) {
        AlbumListVo albumListVo = albumInfoMapper.selectAlbumStatistics(albumId);
        return albumListVo;
    }
}
